/**
 * @Description: 系统工具函数
 * @Author: lujq
 * @Date: 2025-01-04
 * @LastEditors: lujq
 * @LastEditTime: 2025-01-04 10:52:00
 */

import dayjs from 'dayjs'

/**
 * 格式化日期
 * @param date 日期
 * @param format 格式
 * @returns 格式化后的日期字符串
 */
export const formatDate = (date: string | Date, format = 'YYYY-MM-DD HH:mm:ss'): string => {
  return dayjs(date).format(format)
}

/**
 * 格式化日期时间（别名）
 * @param date 日期
 * @param format 格式
 * @returns 格式化后的日期字符串
 */
export const formatDateTime = (date: string | Date, format = 'YYYY-MM-DD HH:mm:ss'): string => {
  return formatDate(date, format)
}

/**
 * 格式化金额
 * @param amount 金额
 * @param currency 货币符号
 * @returns 格式化后的金额字符串
 */
export const formatCurrency = (amount: number, currency = '¥'): string => {
  return `${currency}${amount.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`
}

/**
 * 格式化金额（别名）
 * @param amount 金额
 * @param currency 货币符号
 * @returns 格式化后的金额字符串
 */
export const formatAmount = (amount: number, currency = '¥'): string => {
  return formatCurrency(amount, currency)
}

/**
 * 格式化数字
 * @param num 数字
 * @returns 格式化后的数字字符串
 */
export const formatNumber = (num: number): string => {
  return num.toLocaleString('zh-CN')
}

/**
 * 手机号脱敏
 * @param phone 手机号
 * @returns 脱敏后的手机号
 */
export const maskPhone = (phone: string): string => {
  if (!phone || phone.length < 11) return phone
  return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}

/**
 * 身份证号脱敏
 * @param idCard 身份证号
 * @returns 脱敏后的身份证号
 */
export const maskIdCard = (idCard: string): string => {
  if (!idCard || idCard.length < 15) return idCard
  return idCard.replace(/(\d{6})\d+(\d{4})/, '$1******$2')
}

/**
 * 生成随机ID
 * @param length 长度
 * @returns 随机ID
 */
export const generateId = (length = 8): string => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  let result = ''
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length))
  }
  return result
}

/**
 * 防抖函数
 * @param func 函数
 * @param delay 延迟时间
 * @returns 防抖后的函数
 */
export const debounce = <T extends (...args: any[]) => any>(
  func: T,
  delay: number,
): ((...args: Parameters<T>) => void) => {
  let timeoutId: number
  return (...args: Parameters<T>) => {
    clearTimeout(timeoutId)
    timeoutId = setTimeout(() => func.apply(null, args), delay)
  }
}

/**
 * 节流函数
 * @param func 函数
 * @param delay 延迟时间
 * @returns 节流后的函数
 */
export const throttle = <T extends (...args: any[]) => any>(
  func: T,
  delay: number,
): ((...args: Parameters<T>) => void) => {
  let lastCall = 0
  return (...args: Parameters<T>) => {
    const now = Date.now()
    if (now - lastCall >= delay) {
      lastCall = now
      func.apply(null, args)
    }
  }
}

/**
 * 深拷贝
 * @param obj 对象
 * @returns 深拷贝后的对象
 */
export const deepClone = <T>(obj: T): T => {
  if (obj === null || typeof obj !== 'object') return obj
  if (obj instanceof Date) return new Date(obj.getTime()) as unknown as T
  if (obj instanceof Array) return obj.map((item) => deepClone(item)) as unknown as T
  if (typeof obj === 'object') {
    const clonedObj = {} as T
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = deepClone(obj[key])
      }
    }
    return clonedObj
  }
  return obj
}

/**
 * 获取文件扩展名
 * @param filename 文件名
 * @returns 扩展名
 */
export const getFileExtension = (filename: string): string => {
  return filename.slice(((filename.lastIndexOf('.') - 1) >>> 0) + 2)
}

/**
 * 验证邮箱格式
 * @param email 邮箱
 * @returns 是否有效
 */
export const isValidEmail = (email: string): boolean => {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  return emailRegex.test(email)
}

/**
 * 验证手机号格式
 * @param phone 手机号
 * @returns 是否有效
 */
export const isValidPhone = (phone: string): boolean => {
  const phoneRegex = /^1[3-9]\d{9}$/
  return phoneRegex.test(phone)
}

/**
 * 获取客户等级标签
 * @param level 等级
 * @returns 等级标签配置
 */
export const getCustomerLevelTag = (level: string) => {
  const levelMap = {
    bronze: { label: '青铜', color: '#CD7F32' },
    silver: { label: '白银', color: '#C0C0C0' },
    gold: { label: '黄金', color: '#FFD700' },
    diamond: { label: '钻石', color: '#B9F2FF' },
  }
  return levelMap[level as keyof typeof levelMap] || { label: '未知', color: '#909399' }
}

/**
 * 获取客户等级标签文本
 * @param level 等级
 * @returns 等级标签文本
 */
export const getLevelLabel = (level: string): string => {
  return getCustomerLevelTag(level).label
}

/**
 * 获取订单状态标签
 * @param status 状态
 * @returns 状态标签配置
 */
export const getOrderStatusTag = (status: string) => {
  const statusMap = {
    pending: { label: '待确认', color: '#E6A23C' },
    confirmed: { label: '已确认', color: '#409EFF' },
    production: { label: '生产中', color: '#67C23A' },
    shipped: { label: '已发货', color: '#909399' },
    delivered: { label: '已送达', color: '#67C23A' },
    cancelled: { label: '已取消', color: '#F56C6C' },
  }
  return statusMap[status as keyof typeof statusMap] || { label: '未知', color: '#909399' }
}

/**
 * 获取订单状态标签文本
 * @param status 状态
 * @returns 状态标签文本
 */
export const getOrderStatusLabel = (status: string): string => {
  return getOrderStatusTag(status).label
}

/**
 * 获取支付状态标签
 * @param status 状态
 * @returns 状态标签文本
 */
export const getPaymentStatusTag = (status: string) => {
  const statusMap = {
    unpaid: '未支付',
    partial: '部分支付',
    paid: '已支付',
    refunded: '已退款',
  }
  return statusMap[status as keyof typeof statusMap] || '未知'
}

/**
 * 计算百分比
 * @param value 值
 * @param total 总数
 * @returns 百分比字符串
 */
export const calculatePercentage = (value: number, total: number): string => {
  if (total === 0) return '0%'
  return `${((value / total) * 100).toFixed(1)}%`
}

/**
 * 获取百分比（别名）
 * @param value 值
 * @param total 总数
 * @returns 百分比字符串
 */
export const getPercentage = (value: number, total: number): string => {
  return calculatePercentage(value, total)
}

/**
 * 获取百分比数值（用于进度条等组件）
 * @param value 值
 * @param total 总数
 * @returns 百分比数值
 */
export const getPercentageNumber = (value: number, total: number): number => {
  if (total === 0) return 0
  return Number(((value / total) * 100).toFixed(1))
}

/**
 * 获取随机颜色
 * @returns 随机颜色
 */
export const getRandomColor = (): string => {
  const colors = [
    '#409EFF',
    '#67C23A',
    '#E6A23C',
    '#F56C6C',
    '#909399',
    '#5470C6',
    '#91CC75',
    '#FAC858',
    '#EE6666',
    '#73C0DE',
    '#3BA272',
    '#FC8452',
    '#9A60B4',
    '#EA7CCC',
  ]
  return colors[Math.floor(Math.random() * colors.length)]
}

/**
 * 下载文件
 * @param data 数据
 * @param filename 文件名
 * @param type MIME类型
 */
export const downloadFile = (
  data: any,
  filename: string,
  type = 'application/octet-stream',
): void => {
  const blob = new Blob([data], { type })
  const url = window.URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = filename
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
  window.URL.revokeObjectURL(url)
}

/**
 * 获取图片预览URL
 * @param file 文件
 * @returns Promise<string>
 */
export const getImagePreviewUrl = (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      resolve(e.target?.result as string)
    }
    reader.onerror = reject
    reader.readAsDataURL(file)
  })
}
